package com.lry.pda.bottom.c.backend.executor;

import com.lry.pda.bottom.c.backend.code.CodeKey;
import com.lry.pda.bottom.c.backend.code.CodeNode;
import com.lry.pda.bottom.c.frontend.Grammar;

public class BinaryExecutor extends BaseExecutor{
    @Override
    public void execute(CodeNode root) {
        executeChildren(root);
        CodeNode child;
        int production = (int)root.getAttr(CodeKey.PRODUCTION);

        if(production== Grammar.Unary_TO_Binary){
            child = root.getChildren().get(0);
            copyChild(root, child);
        }
        else if(production == Grammar.Binary_Plus_Binary_TO_Binary){
            //先假设是整形数相加
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 + val2);
            root.setAttr(CodeKey.SYMBOL,root.getChildren().get(0).getAttr(CodeKey.SYMBOL));
            System.out.println("sum of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1+val2) );
        }
        else if(production == Grammar.Binary_Star_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 * val2);

            System.out.println("time of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1*val2) );
        }
        else if(production == Grammar.Binary_Divop_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 / val2);

            System.out.println("divop of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1/val2) );
        }
        else if(production == Grammar.Binary_Mod_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 % val2);

            System.out.println("mod of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1%val2) );
        }
        else if(production == Grammar.Binary_Minus_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 - val2);

            System.out.println("minus of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1-val2) );
        }
        else if(production == Grammar.Binary_LShiftOp_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 << val2);

            System.out.println("left shift of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1<<val2) );
        }
        else if(production == Grammar.Binary_RShiftOp_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 >> val2);

            System.out.println("right shift of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1>>val2) );
        }
        else if(production == Grammar.Binary_And_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 & val2);

            System.out.println("and of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1&val2) );
        }
        else if(production == Grammar.Binary_OR_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 | val2);

            System.out.println("or of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1|val2) );
        }
        else if(production == Grammar.Binary_XOR_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            int val2 = (Integer)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 ^ val2);

            System.out.println("xor of " + root.getChildren().get(0).getAttr(CodeKey.TEXT) + " and "
                    + root.getChildren().get(1).getAttr(CodeKey.TEXT) + " is " + (val1^val2) );
        }

        else if(production == Grammar.Binary_RelOP_Binary_TO_Binary){
            int val1 = (Integer)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            String operator = (String)root.getChildren().get(1).getAttr(CodeKey.TEXT);
            int val2 = (Integer)root.getChildren().get(2).getAttr(CodeKey.VALUE);

            if("==".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 == val2 ? 1 : 0);
            }else if("<".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 < val2? 1 : 0);
            }else if("<=".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 <= val2? 1 : 0);
            }else if(">".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 > val2? 1 : 0);
            }else if(">=".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 >= val2? 1 : 0);
            }else if("!=".equals(operator)){
                root.setAttr(CodeKey.VALUE, val1 != val2? 1 : 0);
            }
        }else if(production==Grammar.BINARY_OROR_BINARY_TO_BINARY){
            boolean val1 = (boolean)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            boolean val2 = (boolean)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 || val2);
        }else if(production==Grammar.BINARY_ANDAND_BINARY_TO_BINARY){
            boolean val1 = (boolean)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            boolean val2 = (boolean)root.getChildren().get(1).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, val1 && val2);
        }else if(production==Grammar.NOT_BINARY_TO_BINARY){
            boolean val = (boolean)root.getChildren().get(0).getAttr(CodeKey.VALUE);
            root.setAttr(CodeKey.VALUE, !val);
        }
    }
}
